home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / renaisnc / lib.lha / Lib / meshrand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-01-04  |  3.4 KB  |  167 lines

  1. /* File: meshrand.c
  2. ** Author: Charles Loop
  3. ** Purpose: Contains routines for generating random points on a 
  4. **          (nonsubdivided) mesh.
  5. ** Last Modified: 11 Nov, 1987
  6. ** Reason : Creation.
  7. ** 
  8. */
  9.  
  10. #include "randgen.h"
  11. #include "graphics.h"
  12. #include "mesh.h"
  13.  
  14. static double SurfaceArea;
  15. static PointType4D p;
  16.  
  17.  
  18. /* compute area of triangle rst */
  19.  
  20. double area(r,s,t)
  21. PointType4D *r,*s,*t;
  22. {
  23.   PointType4D a,b,n;
  24.   double norm;
  25.  
  26.   a.P[X] = s->P[X] - r->P[X];  a.P[Y] = s->P[Y] - r->P[Y];  a.P[Z] = s->P[Z] - r->P[Z];
  27.   b.P[X] = t->P[X] - r->P[X];  b.P[Y] = t->P[Y] - r->P[Y];  b.P[Z] = t->P[Z] - r->P[Z];
  28.  
  29.   n.P[X] = a.P[Y]*b.P[Z] - b.P[Y]*a.P[Z];
  30.   n.P[Y] = a.P[Z]*b.P[X] - b.P[Z]*a.P[X];
  31.   n.P[Z] = a.P[X]*b.P[Y] - b.P[X]*a.P[Y];
  32.  
  33.   if ((norm = n.P[X]*n.P[X] + n.P[Y]*n.P[Y] + n.P[Z]*n.P[Z]) < epsilon)
  34.     return epsilon;
  35.   else
  36.     return sqrt(norm)/2.0;
  37.  
  38. }
  39.  
  40. /*****************************************************************************/
  41.  
  42. Partition(m)
  43.      Mesh *m;
  44. {
  45.   Mesh *mp;
  46.  
  47.   if (m) {
  48.     if (m->type == MESH) {
  49.       if (m->sub.m) {
  50.     for (mp = m->sub.m; mp != (Mesh *) 0; mp = mp->next)
  51.       Partition(mp);
  52.       }
  53.       m->r = SurfaceArea;
  54.     }
  55.     else if (m->type == FACE) {
  56.       if (m->sub.e) {
  57.  
  58.     SurfaceArea += area(m->sub.e->p,
  59.                 m->sub.e->next->p,
  60.                 m->sub.e->next->next->p);
  61.  
  62.     m->r = SurfaceArea;
  63.  
  64.       }
  65.     }
  66.   }
  67. }
  68.  
  69. /*****************************************************************************/
  70.  
  71. MeshPartition(m)
  72.      Mesh *m;
  73. {
  74.   SurfaceArea = 0.0;
  75.   Partition(m);
  76. }
  77.  
  78. /*****************************************************************************/
  79.  
  80. RMP(r,s,t)
  81.      PointType4D *r,*s,*t;
  82. {
  83.   double u,v,w,uvw;
  84.  
  85.   u = random_unif(0.0, 1.0);
  86.   v = random_unif(0.0, 1.0);
  87.   w = random_unif(0.0, 1.0);
  88.   uvw = u + v + w;
  89.   u = u/uvw; v = v/uvw; w = w/uvw;
  90.  
  91.   p.P[X] = u*r->P[X] + v*s->P[X] + w*t->P[X];
  92.   p.P[Y] = u*r->P[Y] + v*s->P[Y] + w*t->P[Y];
  93.   p.P[Z] = u*r->P[Z] + v*s->P[Z] + w*t->P[Z];
  94.  
  95. }
  96.  
  97. /*****************************************************************************/
  98.  
  99. FindFace(m,r)
  100.      Mesh *m;
  101.      double r;
  102. {
  103.   Mesh *mp;
  104.   PointType4D Rp0, Rp1, Rp2;
  105.  
  106.   if (m) {
  107.     if (m->type == MESH) {
  108.       if (mp = m->sub.m) {
  109.  
  110.     while ((mp != (Mesh *) 0) && (r > mp->r))
  111.       mp = mp->next;
  112.  
  113.     FindFace(mp,r);
  114.       }
  115.     }
  116.     else if (m->type == FACE) {
  117.       if (m->sub.e) {
  118.  
  119.     RMP(m->sub.e->p,
  120.         m->sub.e->next->p,
  121.         m->sub.e->next->next->p);
  122.  
  123.       }
  124.     }
  125.     else if (m->type == TRIANGLE) {
  126.       Rp0 = CreatePoint4D(m->sub.t->V[0]->x, m->sub.t->V[0]->y, 
  127.           m->sub.t->V[0]->z, 1.0);
  128.       Rp1 = CreatePoint4D(m->sub.t->V[1]->x, m->sub.t->V[1]->y, 
  129.           m->sub.t->V[1]->z, 1.0);
  130.       Rp2 = CreatePoint4D(m->sub.t->V[2]->x, m->sub.t->V[2]->y, 
  131.           m->sub.t->V[2]->z, 1.0);
  132.       RMP(&Rp0, &Rp1, &Rp2);
  133.     }
  134.     else {
  135.       p.P[X] = random_unif(m->box[X][MIN], m->box[X][MAX]);
  136.       p.P[Y] = random_unif(m->box[Y][MIN], m->box[Y][MAX]);
  137.       p.P[Z] = random_unif(m->box[Z][MIN], m->box[Z][MAX]);
  138.     }
  139.   }
  140. }
  141.  
  142.  
  143. /*****************************************************************************/
  144.  
  145. PointType4D
  146. MeshRandomPoint(m)
  147.      Mesh *m;
  148. {
  149.  
  150. double r;
  151.  
  152.     if( m == (Mesh *)0 ) {
  153.       fprintf(stderr,"Error : Invalid mesh for random point generation\n");
  154.       exit(1);
  155.     }
  156.     if( m->r < epsilon ) {
  157.       fprintf(stderr,"Error: Mesh has no surface area \n");
  158.       exit(1);
  159.     }
  160.  
  161.     r = random_unif(0.0, m->r);
  162.     FindFace(m,r);
  163.     return CreatePoint4D(p.P[X], p.P[Y], p.P[Z], 1.0);
  164.  
  165.  
  166. }
  167.